package com.wootion.dizhi.service;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wootion.dizhi.comon.ResultCode;
import com.wootion.dizhi.comon.TimeHandler;
import com.wootion.dizhi.dao.*;
import com.wootion.dizhi.entity.Config;
import com.wootion.dizhi.entity.Device;
import com.wootion.dizhi.entity.Resources;
import com.wootion.dizhi.entity.Temporary;
import com.wootion.dizhi.response.Result;
import com.wootion.dizhi.runData.GlobalData;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@Service
public class RunDataService {

    @Resource
    DeviceMapper deviceMapper;

    @Autowired
    private WarningMapper warningMapper;

//    @Value("${my.deviceNo}")
//    private String deviceNo;

    private String resources = "./data/";
    private String out = "./out/";

    private String runPath = "./run/";

    @Resource
    private TimeHandler timeHandler;

    @Resource
    private TemporaryDao temporaryDao;

    @Resource
    private ResourcesDao resourcesDao;
    @Resource
    private ConfigurationDao configurationDao;

    public Result start(JSONObject jsonObject) throws IOException {
        Config config = JSONObject.toJavaObject(jsonObject, Config.class);
//        String deviceNo = jsonObject.getString("deviceNo");//设备号
        String number = jsonObject.getString("experiment");//实验次序
        String address = jsonObject.getString("address");//设备地址
        //读取已保存实验的资源
        Integer integer = configurationDao.countByExperiment(number, address);
        if (integer>0){
            return Result.error("此实验次序已存在");
        }
//        Map<String, String> map2 = getXmlFilesInDirectory(resources);
//        Set<String> strings = map2.keySet();
//        if (strings.contains(deviceNo+address+number)){
//            JSONObject jsonObject2 =new JSONObject();
//            jsonObject2.put("code",ResultCode.ERROR.getCode());
//            jsonObject2.put("msg","此实验次序已存在");
//            return jsonObject2;
//        }
        //判断当前设备是否在线
        Boolean run = getRun(address);
        if (!run){
            return Result.error("此设备已离线");
        }
        config.setStartTime(timeHandler.getTimeAsString());//设置记录开始时间
        config.setDeviceName(getDeviceName(address));//设备自定义名称
        //如果当前设备正在记录则拒绝记录操作
        if (GlobalData.RUN_DEVICE_DATA.containsKey(address)&&GlobalData.RUN_DEVICE_DATA.get(address).getString("status").equals(0)){
            return Result.error("此设备正在记录信息");

        }
        //创建运行时数据资源文件 v2.0之后就不需要了
//        File file1 = new File(runPath+deviceNo+address+number+".MA");
//        if (!file1.exists()){
//            file1.createNewFile();
//        }

        //在内存中增加运行配置文件
        GlobalData.RUN_CONFIG.put(address,config);

        //增加设备运行状态
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("number",number);
        jsonObject1.put("status",0);
        GlobalData.RUN_DEVICE_DATA.put(address,jsonObject1);
        return Result.success();
    }

    public Result end(JSONObject jsonObject) throws JAXBException, IOException {

        //获取设备运行状态
        JSONObject jsonObject1 = GlobalData.RUN_DEVICE_DATA.get(jsonObject.getString("address"));
        Integer status = jsonObject1.getInteger("status");
        //记录中的设备能够停止记录
        if (Optional.ofNullable(status).isPresent() && status==0){
            jsonObject1.put("status",1);
            GlobalData.RUN_DEVICE_DATA.put(jsonObject.getString("address"),jsonObject1);
            Config config = GlobalData.RUN_CONFIG.get(jsonObject.getString("address"));

            config.setEndTime(timeHandler.getTimeAsString());
            GlobalData.RUN_CONFIG.put(jsonObject.getString("address") ,config);
            return Result.success();
        }else {
            return Result.error(ResultCode.HAS_STOPED.getMessage());
        }
    }

    public Result getDeviceStatus() {
        Set<String> strings = GlobalData.DEVICE_IS_RUN.keySet();
        List<JSONObject> list = new ArrayList<>();
        for (String s : strings) {//s为设备号+地址值 v2.0之后应该是只有地址值
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("address",s.substring(s.length()-1));//地址,,这里取得是最后一位
            jsonObject.put("deviceNo","占位符");//设备号 这里取得是除最后一位的所有
            jsonObject.put("is_run",GlobalData.DEVICE_IS_RUN.get(s));
            JSONObject jsonObject1 = GlobalData.RUN_DEVICE_DATA.get(s);
            String string1 = jsonObject1.getString("status");//0记录中.1记录结束,3未开始记录
            jsonObject.put("status",string1);
            jsonObject.put("deviceName",getDeviceName(s));
            list.add(jsonObject);
        }
        return Result.success(list);
    }

    public Result save(JSONObject jsonObject) throws IOException, JAXBException {
//        Config config = JSONObject.toJavaObject(jsonObject, Config.class);
//        String deviceNo = jsonObject.getString("deviceNo");//设备号
        String number = jsonObject.getString("experiment");//实验次序
        String address = jsonObject.getString("address");//地址
        Integer order = jsonObject.getInteger("order");//操作

        if (order == 0) {//保存
            Config config = GlobalData.RUN_CONFIG.get(address);
//            String fileDataName =deviceNo+jsonObject.getString("address")+number+".MN";//保存资源的文件,区别于运行时的资源文件MA文件
//            String fileConfigName = deviceNo+jsonObject.getString("address")+number+".xml";//配置文件
            config.setqXnumber(jsonObject.getString("qXnumber"));//取芯回数
            config.setCW(jsonObject.getString("cw"));//层位
            config.setqQXD(jsonObject.getString("qQXD"));//取芯深度
            config.setyPZL(jsonObject.getString("yPZL"));//样品重量
            config.setYpsd(jsonObject.getString("ypsd"));//样品深度

            //将资源文件移动并且重命名
//            Path path = Paths.get(runPath + deviceNo + address + number + ".MA");
//            Path target = Paths.get(resources + fileDataName);
//            Files.move(path,target, StandardCopyOption.REPLACE_EXISTING);
//            config.setDataFile(fileDataName);



            //将配置对象config输出为xml文件 v2.0之后保存在表中
            config.setExportNumber(0);
            String s = IdUtil.simpleUUID();
            config.setId(s);
            Integer integer = configurationDao.insertConfig(config);
            if (integer==0){
                System.out.println("配置保存失败");
            }

            QueryWrapper<Temporary> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("addressExperiment",address+config.getExperiment());
            List<Temporary> temporaries = temporaryDao.selectList(queryWrapper);
            for (Temporary temporary : temporaries) {
                resourcesDao.insert(new Resources(temporary,s));
                temporaryDao.deleteById(temporary);
            }
//            JAXBContext context = JAXBContext.newInstance(Config.class);
//            Marshaller marshaller = context.createMarshaller();
//            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
//            OutputStreamWriter writer = new OutputStreamWriter(
//                    new FileOutputStream(new File(resources + fileConfigName)), "UTF-8");
//            marshaller.marshal(config, writer);
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("status",3);//未记录,重置状态
            GlobalData.RUN_DEVICE_DATA.put(address,jsonObject1);
            GlobalData.RUN_CONFIG.remove(address);//清空内存中记录的实时配置
//            GlobalData.RUN_DATA.remove(deviceNo+address);//清空内存中记录的实时数据
        }else {
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("status",3);//未记录,重置状态
            GlobalData.RUN_DEVICE_DATA.put(address,jsonObject1);
            GlobalData.RUN_CONFIG.remove(address);//清空内存中记录的实时配置
//            GlobalData.RUN_DATA.remove(deviceNo+address);//清空内存中记录的实时数据
        }
        return Result.success();
    }

    /**
     * 获取设备号和地址在设备名称资源文件中的名称
     * @param device
     * @return
     */
    private String getDeviceName(String device){
        Device device1 = deviceMapper.selectById(device);
        if (Optional.ofNullable(device1).isPresent()){
            return device1.getDeviceName();
        }else {
            return " ";
        }

    }

    public Result getConfig(JSONObject jsonObject) {
//        String deviceNo = jsonObject.getString("deviceNo");
        String address = jsonObject.getString("address");
        JSONObject jsonObject1 = GlobalData.RUN_DEVICE_DATA.get(address);
        String string1 = jsonObject1.getString("status");//0记录中,1记录结束,3未开始记录
        //从内存中获取记录中的配置
        Config config = GlobalData.RUN_CONFIG.get(address);
        JSONObject jsonObject11 = null;
        if (Optional.ofNullable(config).isPresent()){
            jsonObject11 = JSONObject.parseObject(JSONObject.toJSONString(config));
            jsonObject11.put("status",string1);
        }
        return Result.success(jsonObject11);
    }

    private Boolean getRun(String address){
        return GlobalData.DEVICE_IS_RUN.get(address);
    };


    public Result selectAllWithPagination(int offset, int size, String address) {
        return Result.success(warningMapper.selectAllWithPagination(offset, size,address));
    }

}
